<template>
  <div class="app-container">
    <el-row :gutter="20" class="novel-page">
      <!-- 左侧AI对话区域 -->
      <el-col :span="8" class="novel-page-left">
        <NovelAiChat
          ref="aiChatRef"
          title="AI主情节设计助手"
          placeholder="请输入您对主情节的要求，例如：我想要一个充满悬疑和冒险的主情节..."
          :loading="aiLoading"
          :enable-context="enableContext"
          :max-context-messages="10"
          @send="handleAiChat"
          @context-change="handleContextChange"
          @abort="handleAbortAI"
        />
      </el-col>

      <!-- 右侧内容编辑区域 -->
      <el-col :span="16" class="novel-page-right">
        <template v-if="currentProject">
          <!-- 项目信息卡片 -->
          <el-card class="box-card mb-20">
            <template #header>
              <div class="card-header">
                <span>项目名称: {{ currentProject.title }}</span>
                <el-button type="success" @click="handleNextStep" v-if="canGoNext">
                  下一步
                </el-button>
              </div>
            </template>
          </el-card>

          <!-- 主情节设计编辑 -->
          <el-card class="box-card">
            <template #header>
              <div class="card-header">
                <span>主情节设计</span>
                <el-button type="primary" @click="handleSave" :loading="saveLoading">
                  {{ currentPlot ? '保存修改' : '保存设定' }}
                </el-button>
              </div>
            </template>
            <el-form
              ref="plotFormRef"
              :model="form"
              :rules="rules"
              label-width="100px"
            >
              <el-form-item label="情节名称" prop="title">
                <el-input v-model="form.title" placeholder="请输入情节名称" />
              </el-form-item>
              <el-form-item label="情节描述" prop="summary">
                <el-input
                  v-model="form.summary"
                  type="textarea"
                  :rows="15"
                  placeholder="请输入情节详细描述，包括情节背景、发展、高潮等内容..."
                />
              </el-form-item>
            </el-form>
          </el-card>
        </template>
        <el-empty v-else description="请先选择或创建一个小说项目" />
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getMainPlot,updateMainPlot,addMainPlot,listMainPlot} from "@/api/novel/mainPlot"
import { getProject } from '@/api/novel/project'
import NovelAiChat from '@/components/NovelAiChat/index.vue'
import { useAIStream, PlatformType, AIModelType } from "@/components/Hook/useStreamFetch"

const route = useRoute()
const router = useRouter()

// 项目数据
const currentProject = ref(null)
const loading = ref(false)
const aiLoading = ref(false)
const saveLoading = ref(false)
const currentPlot = ref(null)
const aiChatRef = ref(null)

// 表单参数
const form = ref({
  id: undefined,
  projectId: undefined,
  title: '',
  summary: ''
})

const rules = ref({
  title: [
    { required: true, message: '情节名称不能为空', trigger: 'blur' }
  ],
  summary: [
    { required: true, message: '情节描述不能为空', trigger: 'blur' }
  ]
})

// 表单引用
const plotFormRef = ref(null)

// 计算属性
const canGoNext = computed(() => {
  return currentProject.value && currentPlot.value
})

// 上下文控制状态
const enableContext = ref(true)

// 世界观设定数据
const worldSetting = ref(null)

// 角色数据
const characters = ref([])

// 获取项目信息
const getProjectInfo = async () => {
  const projectId = route.query.projectId
  if (!projectId) {
    ElMessage.warning('请先选择小说项目')
    router.push('/novel/project')
    return
  }

  try {
    const response = await getProject(projectId.toString())
    currentProject.value = response.data
    form.value.projectId = projectId.toString()
    getPlotInfo()

    // 获取世界观和角色信息
    await getWorldSettingInfo()
    await getCharactersInfo()
  } catch (error) {
    console.error('获取项目信息失败:', error)
    ElMessage.error('获取项目信息失败')
  }
}

// 获取世界观设定
const getWorldSettingInfo = async () => {
  if (!currentProject.value || !currentProject.value.id) {
    return
  }

  try {
    // 导入世界观设定API
    const { getWorldSettingByProject } = await import('@/api/novel/worldSetting')
    const response = await getWorldSettingByProject(currentProject.value.id.toString())

    if (response && response.data) {
      worldSetting.value = response.data
    }
  } catch (error) {
    console.error('获取世界观设定失败:', error)
  }
}

// 获取角色列表
const getCharactersInfo = async () => {
  if (!currentProject.value || !currentProject.value.id) {
    return
  }

  try {
    // 导入角色API
    const { listCharacter } = await import('@/api/novel/character')
    const response = await listCharacter({
      projectId: currentProject.value.id.toString()
    })

    if (response && response.rows) {
      characters.value = response.rows
    }
  } catch (error) {
    console.error('获取角色列表失败:', error)
  }
}

// 获取主情节设计信息
const getPlotInfo = async () => {
  loading.value = true
  try {
    const response = await listMainPlot({
      projectId: currentProject.value.id.toString()
    })

    if (response.rows && response.rows.length > 0) {
      currentPlot.value = response.rows[0]
      form.value = {
        id: currentPlot.value.id ? String(currentPlot.value.id) : undefined,
        projectId: currentPlot.value.projectId ? String(currentPlot.value.projectId) : undefined,
        title: currentPlot.value.title,
        summary: currentPlot.value.summary
      }

      // 如果有现有的主情节设计，将其作为AI的历史回复添加到对话中
      if (currentPlot.value.summary) {
        aiChatRef.value.addAiResponse({
          role: "assistant",
          content: `我已经为您创建了以下主情节设计：\n\n${currentPlot.value.summary}`
        })
      }
    } else {
      currentPlot.value = null
      form.value = {
        id: undefined,
        projectId: currentProject.value.id ? String(currentProject.value.id) : undefined,
        title: '',
        summary: ''
      }
    }
  } catch (error) {
    console.error('获取主情节设计信息失败:', error)
    ElMessage.error('获取主情节设计信息失败')
  } finally {
    loading.value = false
  }
}

// 创建 AI 对话实例
const summaryHook = useAIStream({
  platform: PlatformType.VOLCANO,
  authToken: '02419daf-d6b6-4d07-bdf7-385f483b5bf7',
  model: AIModelType.DEEPSEEK,
  enableContext: true,
  maxContextMessages: 10
})

// 解构出来用于控制和显示
const {
  data: summaryData,
  isLoading: isSummaryLoading,
  error: summaryError,
  chat: startAiChat,
  abortFetch: abortSummary,
  lastMessage
} = summaryHook

// 记录上一次解析的文本长度，用于增量解析
let lastParsedLength = 0;

// 监听AI响应数据，进行实时解析和显示
watch(summaryData, (newVal) => {
  if (newVal) {
    // 更新AI对话内容 - 流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, content: newVal })

    // 更新表单内容
    form.value.summary = newVal

    // 记录解析长度
    lastParsedLength = newVal.length;
  }
})

// 当最后一条消息完成时
watch(lastMessage, (newVal) => {
  if (newVal && !isSummaryLoading.value) {
    // 加载完成时更新表单
    form.value.summary = newVal;
  }
})

// 监听AI加载状态
watch(isSummaryLoading, (isLoading) => {
  aiLoading.value = isLoading
  if (!isLoading) {
    // 结束流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, end: true })
  }
})

// 处理终止AI对话
const handleAbortAI = () => {
  abortSummary()
  aiLoading.value = false
  // 结束流式显示
  aiChatRef.value?.addAiResponse({ isStreaming: true, end: true })
}

// 处理AI对话
const handleAiChat = async (data) => {
  try {
    const { message, context } = data

    // 构建包含前置信息的提示
    let userPrompt = message
    let contextInfo = []

    // 添加世界观上下文
    if (worldSetting.value) {
      contextInfo.push(`【世界观设定】\n名称：${worldSetting.value.name}\n内容：${worldSetting.value.content}`)
    }

    // 添加角色上下文 - 确保角色信息一定会被包含
    if (characters.value && characters.value.length > 0) {
      const protagonists = characters.value.filter(c => c.roleType === 'protagonist').map(c => {
        return `· ${c.name}（${c.gender === 'male' ? '男' : c.gender === 'female' ? '女' : '其他'}，${c.age}岁）：${c.personality}\n  背景：${c.background}`
      }).join('\n\n')

      const antagonists = characters.value.filter(c => c.roleType === 'antagonist').map(c => {
        return `· ${c.name}（${c.gender === 'male' ? '男' : c.gender === 'female' ? '女' : '其他'}，${c.age}岁）：${c.personality}\n  背景：${c.background}`
      }).join('\n\n')

      const supporting = characters.value.filter(c => c.roleType === 'supporting').map(c => {
        return `· ${c.name}（${c.gender === 'male' ? '男' : c.gender === 'female' ? '女' : '其他'}，${c.age}岁）：${c.personality}\n  背景：${c.background}`
      }).join('\n\n')

      let characterSummary = `【角色信息】\n`;

      if (protagonists) characterSummary += `主角：\n${protagonists}\n\n`;
      if (antagonists) characterSummary += `反派：\n${antagonists}\n\n`;
      if (supporting) characterSummary += `配角：\n${supporting}\n\n`;

      contextInfo.push(characterSummary.trim())
    } else {
      // 如果没有角色信息，添加提示
      contextInfo.push(`【角色信息】\n暂无角色信息，请先在角色设定页面添加角色。`)
    }

    // 组合提示词 - 确保角色信息被明确强调
    userPrompt = `${message}`

    // 系统提示词 - 强调角色在情节中的重要性
    const systemPrompt = "你是一个小说助手，请基于以下小说背景信息：\n\n${contextInfo.join('\n\n')}\n\n帮助用户完善主情节设计。请确保所有主要角色在情节中有明确的作用和发展。请按照以下格式输出：\n\n1. 情节背景\n[详细描述情节的背景]\n\n2. 情节发展\n[描述情节的发展过程，包括起因、经过，确保主要角色参与其中]\n\n3. 情节高潮\n[描述情节的高潮部分，展现角色的冲突和成长]\n\n4. 情节结局\n[描述情节的结局和余波，以及对角色的影响]"

    // 开始流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, start: true })

    console.log("开始AI请求:", {
      userPrompt: userPrompt.substring(0, 50) + "...",
      systemPrompt: systemPrompt.substring(0, 50) + "..."
    });

    // 使用优化后的AI聊天函数 - 直接传递消息和系统提示词
    await startAiChat(userPrompt, systemPrompt)

  } catch (error) {
    console.error('AI生成失败:', error)
    ElMessage.error('AI生成失败，请重试')
    // 结束流式显示
    aiChatRef.value?.addAiResponse({ isStreaming: true, end: true })
  } finally {
    aiLoading.value = false
  }
}

// 处理保存
const handleSave = async () => {
  if (!plotFormRef.value) return

  try {
    await plotFormRef.value.validate()
    saveLoading.value = true

    // 使用字符串类型的 ID
    const submitData = {
      ...form.value,
      id: form.value.id ? String(form.value.id) : undefined,
      projectId: form.value.projectId ? String(form.value.projectId) : undefined
    }

    if (currentPlot.value) {
      await updateMainPlot(submitData)
      ElMessage.success('修改成功')
    } else {
      await addMainPlot(submitData)
      ElMessage.success('保存成功')
    }
    getPlotInfo()
  } catch (error) {
    if (error?.message) {
      ElMessage.error(error.message)
    } else {
      console.error('保存失败:', error)
      ElMessage.error('保存失败')
    }
  } finally {
    saveLoading.value = false
  }
}

// 处理下一步
const handleNextStep = () => {
  router.push({
    path: '/novel/volume',
    query: { projectId: currentProject.value.id }
  })
}

// 处理上下文开关变化
const handleContextChange = (value) => {
  if (!value) {
    // 当禁用上下文时，提示用户
    ElMessageBox.confirm(
      '禁用上下文后，AI将无法看到之前的对话历史。确定要禁用吗？',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => {
      // 用户确认后，清空对话历史
      aiChatRef.value?.clearHistory()
      enableContext.value = false
      ElMessage.success('已禁用上下文，对话历史已清空')
    }).catch(() => {
      // 用户取消，保持上下文启用状态
      enableContext.value = true
    })
  } else {
    enableContext.value = true
    ElMessage.success('已启用上下文，AI可以看到之前的对话历史')
  }
}

onMounted(() => {
  getProjectInfo();
})
</script>

<style lang="scss" scoped>
.novel-page {
  height: calc(100vh - 120px);
  padding: 20px;
  .novel-page-left,
  .novel-page-right {
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  .novel-page-right {
    .box-card {
      margin-bottom: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      transition: all 0.3s;
      &:hover {
        box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.2);
      }
    }
  }
}
.mb-20 {
  margin-bottom: 20px;
}
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
}
.el-button {
  border-radius: 4px;
  transition: all 0.3s;
  &:hover {
    transform: translateY(-2px);
  }
}
.el-form-item {
  margin-bottom: 20px;
  transition: all 0.3s;
  &:hover {
    transform: translateX(5px);
  }
}
.el-input,
.el-textarea {
  border-radius: 4px;
  transition: all 0.3s;
  &:focus {
    box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
  }
}
.NovelAiChat {
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
  &:hover {
    box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.2);
  }
}
</style>
